#include <xllp_defs.h>
#include "xllp_mfp_proc_L_LV.h"
#include "xllp_mfp_plat_L_LV.h"
#include "xllp_mfp_rm.h"
#include "xllp_keypad_proc.h"

typedef enum {
    XLLP_RESOURCE_I2C = 0,
    XLLP_RESOURCE_MFPR,          // MFP registers
    XLLP_RESOURCE_MFPR_RM,       // MFP resource manager
    XLLP_RESOURCE_ID_COUNT,
    XLLP_RESOURCE_CLK_EN
} XLLP_PROTECTED_RESOURCES_ID_T; // more IDs might be added

XLLP_STATUS_T XllpLock(XLLP_PROTECTED_RESOURCES_ID_T Xllp_RegisterID)
{
    return 0;
}

XLLP_STATUS_T XllpUnlock(XLLP_PROTECTED_RESOURCES_ID_T Xllp_LockID)
{
    return 0;
}

/******************************************************************************
 * Function: XllpMfpResourceManager
 *
 * Description: Assigns ownership of an MFP to the first claimant or releases
 * ownership if owned and the owner requests release.  Reports conflicts of
 * ownership (claimant ID not the same as owner's ID, if the MFP is already
 * owned)
 *
 * Input Parameters:
 *  pMfpRmDb    - a pointer to MFP resource management database
 *  mfpOffset   - The offset of the MFPR for the MFP that is being
 *          claimed or released. One of the XLLP_MFP_[usageName]
 *          _OFFSET constants in the range of 0.. XLLP_MFP_PIN_
 *          MAX_OFFSET (inclusive)
 *  claimantId  - The identifier of the module that wants to claim or
 *          release the specified MFP. It must be unique within
 *          the BSP (not checked) and (for the initial implementa-
 *          tion) fall within the range of 0x10..0xFF (checked).
 *          0x00 through 0x0F are reserved for XLLP MFP usage.
 *          0x10 .. 0x8F are reserved for XLLP module IDs.  0x90
 *          ..0xFF are reserved for OS-assigned IDs.
 *  claimAction - XLLP_SET  = claim ownership
 *          - XLLP_CLEAR    = release ownership
 *
 * Returns:
 *  XLLP_STATUS_SUCCESS     - All parameters were valid.
 *  XLLP_STATUS_WRONG_PARAMETER - Null pointer received or parameter
 *      is out of range.
 *  XLLP_STATUS_NO_RESOURCES    - The MFP ownership is already
 *      assigned to another ID.
 *
 * Global effects:
 *
 * Assumptions:
 *
 * Calls:
 *
 * Called by:
 *
 * Prototype:
 * XLLP_STATUS_T XllpMfpResourceManager(
 *              P_XLLP_MFP_RM_DB_ID_T   pMfpRmDb,
 *              XLLP_UINT32_T       mfpOffset,
 *              XLLP_MFP_RM_DB_ID_T claimantId,
 *              XLLP_UINT32_T       claiAction)
 ******************************************************************************/
XLLP_STATUS_T XllpMfpResourceManager(
        P_XLLP_MFP_RM_DB_ID_T   pMfpRmDb,
        XLLP_UINT32_T       mfpOffset,
        XLLP_MFP_RM_DB_ID_T claimantId,
        XLLP_UINT32_T       claimAction)
{
#if defined(XLLP_DEBUG_PARAM_CHECK)
    if (!pMfpRmDb)
        return(XLLP_STATUS_WRONG_PARAMETER);

    if ((mfpOffset < XLLP_MFP_PIN_MIN_OFFSET) ||
            (mfpOffset > XLLP_MFP_PIN_MAX_OFFSET))
        return(XLLP_STATUS_WRONG_PARAMETER);

    if (mfpOffset & 0x3){
        return(XLLP_STATUS_WRONG_PARAMETER); }

    /* Need a macro to define the range of claimantId. -stanley */
    // At first, just check for max ID - carl
    // if ((claimantId > XLLP_MFP_RM_ID_MAX) ||
    //     (claimantId < XLLP_MFP_RM_ID_XLLP_BASE))
    if (claimantId > XLLP_MFP_RM_ID_MAX)
        return(XLLP_STATUS_WRONG_PARAMETER);

    switch (claimAction) {

        case XLLP_SET:
            break;
        case XLLP_CLEAR:
            break;
        default:
            return (XLLP_STATUS_WRONG_PARAMETER);
    }

#endif //defined(XLLP_DEBUG_PARAM_CHECK)

    if (XLLP_MFP_RM_ID_PM != pMfpRmDb[mfpOffset>>2]) {

        if (pMfpRmDb[mfpOffset>>2] && pMfpRmDb[mfpOffset>>2] != claimantId) {
            return XLLP_STATUS_NO_RESOURCES;
        }
        else {
            pMfpRmDb[mfpOffset>>2] =
                (XLLP_SET == claimAction) ? claimantId : 0;
        }
    }
    return(XLLP_STATUS_SUCCESS);

}  // XllpMfpResourceManager()

/******************************************************************************
 * Function: XllpMfpResourceManager_List
 *
 * Description: Performs exactly the same operation as XllpMfpResourceManager
 * (), but on a list of MFPR offsets.
 *
 * Input Parameters:
 *  pMfpRmDb    - a pointer to MFP resource management database
 *  pMfpOffsetList  - Pointer to a list of offsets of the MFPRs for the
 *          MFP that are being claimed or released.  The target
 *          values must all be in the set of XLLP_MFP_[usageName]
 *          _OFFSET constants in the range of 0..XLLP_MFP_PIN_MAX
 *          _OFFSET (inclusive).  Must end in XLLP_MFP_PIN_EOLIST
 *          _MARKER.
 *  claimantId  - The identifier of the module that wants to claim or
 *          release the specified MFP.  It must be unique within
 *          the BSP (not checked) and (for the initial implementa-
 *          tion) fall within the range of 0x10..0xFF (checked).
 *          0x00 through 0x0F are reserved for XLLP MFP usage.
 *          0x10 .. 0x8F are reserved for XLLP module IDs.  0x90
 *          ..0xFF are reserved for OS-assigned IDs.
 *  claimAction - XLLP_SET  = claim ownership
 *          - XLLP_CLEAR    = release ownership
 *
 * Returns:
 *  XLLP_STATUS_SUCCESS     - All parameters were valid.
 *  XLLP_STATUS_WRONG_PARAMETER - Null pointer received or parameter
 *      is out of range.
 *  XLLP_STATUS_NO_RESOURCES    - The MFP ownership is already
 *      assigned to another ID.
 *
 * Global effects:
 *
 * Assumptions:
 *
 * Calls:
 *
 * Called by:
 *
 * Prototype:
 * XLLP_STATUS_T XllpMfpResourceManager_List(
 *              P_XLLP_MFP_RM_DB_ID_T   pMfpRmDb,
 *              P_XLLP_UINT32_T     pMfpOffsetList,
 *              XLLP_MFP_RM_DB_ID_T claimantId,
 *              XLLP_UINT32_T       claiAction)
 ******************************************************************************/
XLLP_STATUS_T XllpMfpResourceManager_List (
        P_XLLP_MFP_RM_DB_ID_T   pMfpRmDb,
        P_XLLP_UINT32_T     pMfpOffsetList,
        XLLP_MFP_RM_DB_ID_T claimantId,
        XLLP_UINT32_T       claimAction)
{
    XLLP_STATUS_T status = XLLP_STATUS_SUCCESS;

#if defined(XLLP_DEBUG_PARAM_CHECK)
    if (!pMfpRmDb || !pMfpOffsetList)
        return(XLLP_STATUS_WRONG_PARAMETER);
#endif

    XllpLock(XLLP_RESOURCE_MFPR_RM);

    while ((XLLP_STATUS_SUCCESS == status)
            && (XLLP_MFP_PIN_EOLIST_MARKER != *pMfpOffsetList)) {
        status = XllpMfpResourceManager(pMfpRmDb, *pMfpOffsetList,
                claimantId, claimAction);
        pMfpOffsetList ++;
    }

    XllpUnlock(XLLP_RESOURCE_MFPR_RM);

    return(status);

}  // XllpMfpResourceManager_List()

/******************************************************************************
 * Function: XllpMfpResourceManagerInit
 *
 * Description: Initializes the database for the XLLP MFP Resource Manager
 *
 * Input Parameters:
 *  pMfpRmDb    - a pointer to MFP resource management database
 *
 * Returns:
 *  XLLP_STATUS_SUCCESS     - All parameters were valid.
 *  XLLP_STATUS_WRONG_PARAMETER - Null pointer received or parameter
 *      is out of range.
 *
 * Global effects:
 *
 * Assumptions:
 *
 * Calls:
 *
 * Called by:
 *
 * Prototype:
 * XLLP_STATUS_T XllpMfpResourceManagerInit(P_XLLP_MFP_RM_DB_ID_T pMfpRmDb);
 ******************************************************************************/
XLLP_STATUS_T XllpMfpResourceManagerInit (P_XLLP_MFP_RM_DB_ID_T pMfpRmDb)
{
    XLLP_UINT32_T i;
#if defined(XLLP_DEBUG_PARAM_CHECK)
    if (!pMfpRmDb)
        return(XLLP_STATUS_WRONG_PARAMETER);
#endif // defined(XLLP_DEBUG_PARAM_CHECK)

    for (i=0; i < (XLLP_MFP_RM_DB_SIZE / sizeof(XLLP_MFP_RM_DB_ID_T)); i++)
        pMfpRmDb[i] = 0u;

    return(XLLP_STATUS_SUCCESS);

} // XllpMfpResourceManagerInit()

/******************************************************************************
 * Function: XllpMfpGetPinConfig
 *
 * Description: Reads from HW (MFPR) the current configuration of the
 *  specified MFP.  This is an uninterpreted value.  It is expected to be
 *  principally of interest for debug or for "locking" reads.
 *
 * Input Parameters:
 *  pMfpRegBase - base address of the MFP register set
 *  mfpOffset:  The offset of a variable to receive the pin configuration.
 *
 * Output Parameters:
 *  pMfpConfig: Virtual base address of the MFP register set
 *
 * Returns:
 *  XLLP_STATUS_SUCCESS     - All parameters were valid.
 *  XLLP_STATUS_WRONG_PARAMETER - Null pointer received or parameter
 *      is out of range.
 *
 * Global effects:
 *
 * Assumptions:
 *
 * Calls:
 *
 * Called by:
 *
 * Prototype:
 * XLLP_STATUS_T XllpMfpGetPinConfig (
 *              P_XLLP_UINT32_T     pMfpRegBase,
 *              XLLP_UINT32_T       mfpOffset,
 *              P_XLLP_VUINT32_T    pMfpConfig
 *              )
 ******************************************************************************/
XLLP_STATUS_T XllpMfpGetPinConfig (
        P_XLLP_VUINT32_T    pMfpRegBase,
        XLLP_UINT32_T       mfpOffset,
        P_XLLP_VUINT32_T    pMfpConfig)
{
#if defined(XLLP_DEBUG_PARAM_CHECK)
    if (!pMfpRegBase)
        return(XLLP_STATUS_WRONG_PARAMETER);

    if ((mfpOffset < XLLP_MFP_PIN_MIN_OFFSET) ||
            (mfpOffset > XLLP_MFP_PIN_MAX_OFFSET))
        return(XLLP_STATUS_WRONG_PARAMETER);

    if (mfpOffset & 0x3)
        return(XLLP_STATUS_WRONG_PARAMETER);
#endif // defined(XLLP_DEBUG_PARAM_CHECK)

#if defined(CONFIG_CPU_MONAHANS_PL) || defined(CONFIG_CPU_MONAHANS_L) || defined(CONFIG_CPU_MONAHANS_LV)
    /* The expand GPIO pins just have one function */
    if (mfpOffset >= XLLP_EXP_GPIO_START_OFFSET){
        *pMfpConfig = 0;
        return(XLLP_STATUS_SUCCESS);
    }
#endif

    *pMfpConfig = *(pMfpRegBase + (mfpOffset>>2));

    return(XLLP_STATUS_SUCCESS);
} // XllpMfpGetPinConfig()

/* The implementation is TBD. -stanley */
XLLP_STATUS_T XllpMfpInitUnusedPin (
        P_XLLP_VUINT32_T        pMfpRegBase,
        XLLP_UINT32_T           mfpOffset,
        XLLP_MFP_CONFIGURE_PULL_T   pullConfigure
        )
{
    return(XLLP_STATUS_SUCCESS);
}

/* The implementation is TBD. -stanley */
XLLP_STATUS_T XllpMfpInitUnusedPin_List (
        P_XLLP_VUINT32_T        pMfpRegBase,
        P_XLLP_UINT32_T         pMfpOffsetList,
        P_XLLP_MFP_CONFIGURE_PULL_T pPullConfigureList
        )
{
    return(XLLP_STATUS_SUCCESS);
}

/******************************************************************************
 * Function: XllpMfpSetAfDs
 *
 * Description: Sets the specified MFP to select the specified Alternate
 *  Function and Drive Strength.  Performs a read-modify-write operation
 *  that only changes the Alternate Function and Drive Strength bit fields.
 *
 * Input Parameters:
 *  pMfpRegBase - base address of the MFP register set
 *  mfpOffset   - The offset of a variable to receive the pin
 *          configuration.
 *  afCode      - The desired Alternate Function value
 *  driveStrength   - The desired drive strength code.
 *
 * Returns:
 *  XLLP_STATUS_SUCCESS     - All parameters were valid.
 *  XLLP_STATUS_WRONG_PARAMETER - Null pointer received or parameter
 *      is out of range.
 *
 * Global effects:
 *
 * Assumptions:
 *
 * Calls:
 *
 * Called by:
 *
 * Prototype:
 * XLLP_STATUS_T XllpMfpSetAfDs (
 *              P_XLLP_UINT32_T     pMfpRegBase,
 *              XLLP_UINT32_T       mfpOffset,
 *              XLLP_MFP_ALT_FN_T   afCode,
 *              XLLP_MFP_DRIVE_STRENGTH_T   driveStrength
 *              )
 ******************************************************************************/
XLLP_STATUS_T XllpMfpSetAfDs (
        P_XLLP_VUINT32_T        pMfpRegBase,
        XLLP_UINT32_T           mfpOffset,
        XLLP_MFP_ALT_FN_T       afCode,
        XLLP_MFP_DRIVE_STRENGTH_T   driveStrength)
{
    XLLP_INT32_T value;

#if defined(XLLP_DEBUG_PARAM_CHECK)
    if (!pMfpRegBase)
        return(XLLP_STATUS_WRONG_PARAMETER);

    if ((mfpOffset < XLLP_MFP_PIN_MIN_OFFSET) ||
            (mfpOffset > XLLP_MFP_PIN_MAX_OFFSET))
        return(XLLP_STATUS_WRONG_PARAMETER);

    if (mfpOffset & 0x3)
        return(XLLP_STATUS_WRONG_PARAMETER);

    if ((afCode > XLLP_MFP_ALT_FN_MAX) ||
            (driveStrength > XLLP_MFP_DS_MAX))
        return(XLLP_STATUS_WRONG_PARAMETER);
#endif // defined(XLLP_DEBUG_PARAM_CHECK)

#if defined(CONFIG_CPU_MONAHANS_PL) || defined(CONFIG_CPU_MONAHANS_L) || defined(CONFIG_CPU_MONAHANS_LV)
    /* The expand GPIO pins just have one function */
    if (mfpOffset >= XLLP_EXP_GPIO_START_OFFSET)
        return(XLLP_STATUS_SUCCESS);
#endif

    /* Will we keep the original pull up/down setting? -stanley */
    /* Use a different function for that - carl*/
    value = *(pMfpRegBase + (mfpOffset>>2));
    value &= ~((0x7 << 10) | 0x7);
    value |= (driveStrength << 10) | afCode;
    *(pMfpRegBase + (mfpOffset>>2)) = value;
    return(XLLP_STATUS_SUCCESS);
}

/******************************************************************************
 * Function: XllpMfpSetAfDs_List
 *
 * Description: Performs exactly the same operation as XllpMfpSetAfDs (), but
 *  on a list of MFPR offsets and lists of corresponding Alternate Function
 *  and Drive Strength settings
 *
 * Input Parameters:
 *  pMfpRegBase - base address of the MFP register set
 *  pMfpOffsetList  - Pointer to a list of offsets of the MFPRs that
 *      are being set to the the corresponding specified Alternate
 *      Function and Drive Strength settings.  Must end in
 *      XLLP_MFP_PIN_EOLIST_MARKER
 *  pAfCodeList - Pointer to a list of Alternate Function selector
 *      values for the MFPRs in the *pMfpOffsetList.  The values
 *      will be applied, in order, to the MFPR offsets in the offset
 *      list (first value to the first MFPR, second to the second,
 *      etc.).  No terminating marker value is required.
 *  pDriveStrengthList  - Pointer to a list of Drive Strength
 *      selector values for the MFPRs in the *pMfpOffsetList. The
 *      values will be applied, in order, to the MFPR offsets in the
 *      offset list (first value to the first MFPR, second to the
 *      second, etc.).  No terminating marker value is required
 *
 * Returns:
 *  XLLP_STATUS_SUCCESS     - All parameters were valid.
 *  XLLP_STATUS_WRONG_PARAMETER - Null pointer received or parameter
 *      is out of range.
 *
 * Global effects:
 *
 * Assumptions:
 *
 * Calls:
 *
 * Called by:
 *
 * Prototype:
 * XLLP_STATUS_T XllpMfpSetAfDs_List (
 *              P_XLLP_UINT32_T         pMfpRegBase,
 *              P_XLLP_UINT32_T         pMfpOffsetList,
 *              P_XLLP_MFP_ALT_FN_T     pAfCodeList,
 *              P_XLLP_MFP_DRIVE_STRENGTH_T pDriveStrengthList
 *              )
 ******************************************************************************/
XLLP_STATUS_T XllpMfpSetAfDs_List (
        P_XLLP_VUINT32_T        pMfpRegBase,
        P_XLLP_UINT32_T         pMfpOffsetList,
        P_XLLP_MFP_ALT_FN_T     pAfCodeList,
        P_XLLP_MFP_DRIVE_STRENGTH_T pDriveStrengthList)
{
    XLLP_STATUS_T status;

#if defined(XLLP_DEBUG_PARAM_CHECK)
    if (!pMfpRegBase || !pMfpOffsetList || !pAfCodeList ||
            !pDriveStrengthList)
        return(XLLP_STATUS_WRONG_PARAMETER);
#endif // defined(XLLP_DEBUG_PARAM_CHECK)

    while (*pMfpOffsetList != XLLP_MFP_PIN_EOLIST_MARKER) {
        status = XllpMfpSetAfDs( pMfpRegBase, *pMfpOffsetList,
                *pAfCodeList, *pDriveStrengthList);
        if (status != XLLP_STATUS_SUCCESS)
            return status;
        /* The offset is correct??? -stanley */
        pMfpOffsetList ++;
        pAfCodeList ++;
        pDriveStrengthList ++;
    }

    return(XLLP_STATUS_SUCCESS);
}

/******************************************************************************
 * Function: XllpMfpConfigureWakeup
 *
 * Description: Configures the specified MFP provide a wake up indicator
 *  based on the specified edge trigger.  Performs a read-modify-write
 *  operation that only changes the edge trigger direction (rising,
 *  falling) bit fields
 *
 * Input Parameters:
 *  pMfpRegBase - base address of the MFP register set
 *  mfpOffset   - The offset of the MFPR that is being set to the
 *          specified edge trigger
 *  edgeTrigger: The desired edge trigger direction code
 *
 * Returns:
 *  XLLP_STATUS_SUCCESS     - All parameters were valid.
 *  XLLP_STATUS_WRONG_PARAMETER - Null pointer received or parameter
 *      is out of range.
 *
 * Global effects:
 *
 * Assumptions:
 *
 * Calls:
 *
 * Called by:
 *
 * Prototype:
 * XLLP_STATUS_T XllpMfpConfigureWakeup (
 *              P_XLLP_UINT32_T   pMfpRegBase,
 *              XLLP_UINT32_T   mfpOffset,
 *              XLLP_MFP_EDGE_T edgeTrigger
 *              )
 ******************************************************************************/
XLLP_STATUS_T XllpMfpConfigureWakeup (
        P_XLLP_VUINT32_T pMfpRegBase,
        XLLP_UINT32_T   mfpOffset,
        XLLP_MFP_EDGE_T edgeTrigger)
{
    XLLP_INT32_T value;

#if defined(XLLP_DEBUG_PARAM_CHECK)
    if (!pMfpRegBase)
        return(XLLP_STATUS_WRONG_PARAMETER);

    if ((mfpOffset < XLLP_MFP_PIN_MIN_OFFSET) ||
            (mfpOffset > XLLP_MFP_PIN_MAX_OFFSET))
        return(XLLP_STATUS_WRONG_PARAMETER);

    if (edgeTrigger > XLLP_MFP_EDGE_MAX)
        return(XLLP_STATUS_WRONG_PARAMETER);
#endif // defined(XLLP_DEBUG_PARAM_CHECK)

#if defined(CONFIG_CPU_MONAHANS_PL) || defined(CONFIG_CPU_MONAHANS_L) || defined(CONFIG_CPU_MONAHANS_LV)
    /* The expand GPIO pins just have one function */
    if (mfpOffset >= XLLP_EXP_GPIO_START_OFFSET)
        return(XLLP_STATUS_SUCCESS);
#endif

    value = *(pMfpRegBase + (mfpOffset>>2));
    value &= ~(0x3<<4);
    value |= edgeTrigger<<4;
    *(pMfpRegBase + (mfpOffset>>2)) = value;

    return(XLLP_STATUS_SUCCESS);
}

/******************************************************************************
 * Function: XllpMfpConfigureWakeup_List
 *
 * Description: Performs exactly the same operation as XllpMfpCOnfigureWakeup
 *  (), but on a list of MFPR offsets and lists of Edge Trigger direction
 *  code.
 *
 * Input Parameters:
 *  pMfpRegBase - base address of the MFP register set
 *  pMfpOffsetList  - A pointer to the list of the offset of the MFPR that
 *          is being set to the specified edge trigger
 *  pEdgeTriggerList- A pointer to the list of the desired edge trigger
 *          direction code
 *
 * Returns:
 *  XLLP_STATUS_SUCCESS     - All parameters were valid.
 *  XLLP_STATUS_WRONG_PARAMETER - Null pointer received or parameter
 *      is out of range.
 *
 * Global effects:
 *
 * Assumptions:
 *
 * Calls:
 *
 * Called by:
 *
 * Prototype:
 * XLLP_STATUS_T XllpMfpConfigureWakeup_List (
 *              P_XLLP_UINT32_T pMfpRegBase,
 *              P_XLLP_UINT32_T pMfpOffsetList,
 *              P_XLLP_MFP_EDGE_T pEdgeTriggerList
 *              )
 ******************************************************************************/
XLLP_STATUS_T XllpMfpConfigureWakeup_List (
        P_XLLP_VUINT32_T    pMfpRegBase,
        P_XLLP_UINT32_T     pMfpOffsetList,
        P_XLLP_MFP_EDGE_T   pEdgeTriggerList)
{
    XLLP_STATUS_T status;

#if defined(XLLP_DEBUG_PARAM_CHECK)
    if (!pMfpRegBase || !pMfpOffsetList || !pEdgeTriggerList)
        return(XLLP_STATUS_WRONG_PARAMETER);
#endif // defined(XLLP_DEBUG_PARAM_CHECK)

    while (*pMfpOffsetList != XLLP_MFP_PIN_EOLIST_MARKER) {
        status = XllpMfpConfigureWakeup(pMfpRegBase, *pMfpOffsetList,
                *pEdgeTriggerList);
        if (status != XLLP_STATUS_SUCCESS)
            return status;

        pMfpOffsetList ++;
        pEdgeTriggerList ++;
    }

    return(XLLP_STATUS_SUCCESS);
}

/******************************************************************************
 * Function: XllpMfpEnableWakeup
 *
 * Description: Enables or disables waking up based on the configured edge
 *  trigger in the specified MFP. Performs a read-modify-write operation
 *  that only changes the edge trigger enable bit field.
 *
 * Input Parameters:
 *  pMfpRegBase - base address of the MFP register set
 *  mfpOffset   - The offset of the MFPR that is being set to the
 *          specified edge trigger
 *  enable      -
 *      XLLP_ON:  Enable wakeup based on the configured edge trigger.
 *      XLLP_OFF: Disable wakeup based on the configured edge trigger
 *
 * Returns:
 *  XLLP_STATUS_SUCCESS     - All parameters were valid.
 *  XLLP_STATUS_WRONG_PARAMETER - Null pointer received or parameter
 *      is out of range.
 *
 * Global effects:
 *
 * Assumptions:
 *
 * Calls:
 *
 * Called by:
 *
 * Prototype:
 * XLLP_STATUS_T XllpMfpEnableWakeup (
 *              P_XLLP_UINT32_T   pMfpRegBase,
 *              XLLP_UINT32_T   mfpOffset,
 *              XLLP_CONTROL_T  enable
 *              )
 ******************************************************************************/
XLLP_STATUS_T XllpMfpEnableWakeup (
        P_XLLP_VUINT32_T pMfpRegBase,
        XLLP_UINT32_T   mfpOffset,
        XLLP_CONTROL_T  enable)
{
    XLLP_INT32_T value;

#if defined(XLLP_DEBUG_PARAM_CHECK)
    if (!pMfpRegBase)
        return(XLLP_STATUS_WRONG_PARAMETER);

    if ((mfpOffset < XLLP_MFP_PIN_MIN_OFFSET) ||
            (mfpOffset > XLLP_MFP_PIN_MAX_OFFSET))
        return(XLLP_STATUS_WRONG_PARAMETER);

    if ((enable != XLLP_ON) && (enable != XLLP_OFF))
        return(XLLP_STATUS_WRONG_PARAMETER);
#endif // defined(XLLP_DEBUG_PARAM_CHECK)

#if defined(CONFIG_CPU_MONAHANS_PL) || defined(CONFIG_CPU_MONAHANS_L) || defined(CONFIG_CPU_MONAHANS_LV)
    /* The expand GPIO pins just have one function */
    if (mfpOffset >= XLLP_EXP_GPIO_START_OFFSET)
        return(XLLP_STATUS_SUCCESS);
#endif

    value = *(pMfpRegBase + (mfpOffset>>2));
    value &= ~(0x1<<6);
    if (enable == XLLP_OFF)
        value |= (0x1<<6);
    *(pMfpRegBase + (mfpOffset>>2)) = value;

    return(XLLP_STATUS_SUCCESS);
}

/******************************************************************************
 * Function: XllpMfpEnableWakeup_List
 *
 * Description: Performs exactly the same operation as XllpMfpEnableWakeup(),
 *  but on a list of MFPR offsets.  Applies the same enable or disable of
 *  Edge Trigger direction to all listed MFPs.
 *
 * Input Parameters:
 *  pMfpRegBase - base address of the MFP register set
 *  pMfpOffsetList  - A pointer to the list of the offset of the MFPR that
 *          is being set to the specified edge trigger
 * enable:
 *  XLLP_ON:  Enable LPM wakeup based on the configured edge triggers for all
 *             listed MFPs.
 *  XLLP_OFF: Disable LPM wakeup from all listed MFPs and clear their triggers.
 *
 * Returns:
 *  XLLP_STATUS_SUCCESS     - All parameters were valid.
 *  XLLP_STATUS_WRONG_PARAMETER - Null pointer received or parameter
 *      is out of range.
 *
 * Global effects:
 *
 * Assumptions:
 *
 * Calls:
 *
 * Called by:
 *
 * Prototype:
 * XLLP_STATUS_T XllpMfpEnableWakeup_List (
 *              P_XLLP_UINT32_T pMfpRegBase,
 *              XLLP_UINT32_T   pMfpOffsetList,
 *              XLLP_CONTROL_T  enableList
 *              )
 ******************************************************************************/
XLLP_STATUS_T XllpMfpEnableWakeup_List (
        P_XLLP_VUINT32_T    pMfpRegBase,
        P_XLLP_UINT32_T     pMfpOffsetList,
        XLLP_CONTROL_T      enable)
{
    XLLP_STATUS_T status;

#if defined(XLLP_DEBUG_PARAM_CHECK)
    if (!pMfpRegBase || !pMfpOffsetList)
        return(XLLP_STATUS_WRONG_PARAMETER);
#endif // defined(XLLP_DEBUG_PARAM_CHECK)

    while (*pMfpOffsetList != XLLP_MFP_PIN_EOLIST_MARKER) {
        status = XllpMfpEnableWakeup(pMfpRegBase, *pMfpOffsetList,
                enable);
        if (status != XLLP_STATUS_SUCCESS)
            return status;

        pMfpOffsetList ++;
    }

    return(XLLP_STATUS_SUCCESS);
}

/******************************************************************************
 * Function: XllpMfpConfigurePullUpDown
 *
 * Description: Configures the specified MFP to use one of the three valid
 *  settings for the (internal) output pull up and pull down resistors,
 *  when that output is activated. Performs a read-modify-write operation
 *  that only changes the pull resistors control bit field.
 *
 * Input Parameters:
 *  pMfpRegBase - base address of the MFP register set
 *  mfpOffset   - The offset of the MFPR that is being set to the
 *          specified edge trigger
 *  pullConfigure   - Selects among pull up only, pull down only, or do
 *          not pull
 *
 * Returns:
 *  XLLP_STATUS_SUCCESS     - All parameters were valid.
 *  XLLP_STATUS_WRONG_PARAMETER - Null pointer received or parameter
 *      is out of range.
 *
 * Global effects:
 *
 * Assumptions:
 *
 * Calls:
 *
 * Called by:
 *
 * Prototype:
 * XLLP_STATUS_T XllpMfpConfigurePullUpDown (
 *              P_XLLP_VUINT32_T  pMfpRegBase,
 *              XLLP_UINT32_T   mfpOffset,
 *              XLLP_MFP_CONFIGURE_PULL_T   pullConfigure
 *              )
 ******************************************************************************/
XLLP_STATUS_T XllpMfpConfigurePullUpDown (
        P_XLLP_VUINT32_T        pMfpRegBase,
        XLLP_UINT32_T           mfpOffset,
        XLLP_MFP_CONFIGURE_PULL_T   pullConfigure)
{
    XLLP_INT32_T value;

#if defined(XLLP_DEBUG_PARAM_CHECK)
    if (!pMfpRegBase)
        return(XLLP_STATUS_WRONG_PARAMETER);

    if ((mfpOffset < XLLP_MFP_PIN_MIN_OFFSET) ||
            (mfpOffset > XLLP_MFP_PIN_MAX_OFFSET))
        return(XLLP_STATUS_WRONG_PARAMETER);

    /*
       pullConfigure - XLLP_PULLUP - 0x2
       - XLLP_PULLDOWN - 0x1
       XLLP_PULL_NONE -0x0
       */
    if (pullConfigure > XLLP_MFP_PULL_MAX)
        return(XLLP_STATUS_WRONG_PARAMETER);
#endif //defined(XLLP_DEBUG_PARAM_CHECK)

#if defined(CONFIG_CPU_MONAHANS_PL) || defined(CONFIG_CPU_MONAHANS_L) || defined(CONFIG_CPU_MONAHANS_LV)
    /* The expand GPIO pins just have one function */
    if (mfpOffset >= XLLP_EXP_GPIO_START_OFFSET)
        return(XLLP_STATUS_SUCCESS);
#endif

    value = *(pMfpRegBase + (mfpOffset>>2));
    value &= ~(0x3<<13);
    value |= (pullConfigure<<13);
    *(pMfpRegBase + (mfpOffset>>2)) = value;

    return(XLLP_STATUS_SUCCESS);
}

/******************************************************************************
 * Function: XllpMfpConfigurePullUpDown_List
 *
 * Description: Performs exactly the same operation as
 *  XllpMfpConfigurePullUpDown(), but on a list of MFPR offsets and lists
 *  of for selectting among pull up only, pull down only, or do not pull
 *
 * Input Parameters:
 *  pMfpRegBase - base address of the MFP register set
 *  pMfpOffsetList  - A pointer to the list for the offset of the MFPR
 *          that is being set to the specified edge trigger
 *  pPullConfigureList- A pointer to the list for selectting among pull
 *          up only, pull down only, or do not pull
 *
 * Returns:
 *  XLLP_STATUS_SUCCESS     - All parameters were valid.
 *  XLLP_STATUS_WRONG_PARAMETER - Null pointer received or parameter
 *      is out of range.
 *
 * Global effects:
 *
 * Assumptions:
 *
 * Calls:
 *
 * Called by:
 *
 * Prototype:
 * XLLP_STATUS_T XllpMfpConfigurePullUpDown_List (
 *              P_XLLP_VUINT32_T  pMfpRegBase,
 *              P_XLLP_UINT32_T pMfpOffset_List,
 *              P_XLLP_MFP_CONFIGURE_PULL_T pPullConfigureList
 *              )
 ******************************************************************************/
XLLP_STATUS_T XllpMfpConfigurePullUpDown_List (
        P_XLLP_VUINT32_T    pMfpRegBase,
        P_XLLP_UINT32_T     pMfpOffsetList,
        P_XLLP_MFP_CONFIGURE_PULL_T pPullConfigureList)
{
    XLLP_STATUS_T status;

#if defined(XLLP_DEBUG_PARAM_CHECK)
    if (!pMfpRegBase || !pMfpOffsetList || !pPullConfigureList)
        return(XLLP_STATUS_WRONG_PARAMETER);
#endif // defined(XLLP_DEBUG_PARAM_CHECK)

    while (*pMfpOffsetList != XLLP_MFP_PIN_EOLIST_MARKER) {
        status = XllpMfpConfigurePullUpDown(pMfpRegBase,
                *pMfpOffsetList, *pPullConfigureList);
        if (status != XLLP_STATUS_SUCCESS)
            return status;

        pMfpOffsetList ++;
        pPullConfigureList ++;
    }

    return(XLLP_STATUS_SUCCESS);
}

/******************************************************************************
 * Function: XllpMfpActivatePullUpDown
 *
 * Description: Configures the specified MFP to use one of the three valid
 *  settings for the (internal) output pull up and pull down resistors,
 *  when that output is activated. Performs a read-modify-write operation
 *  that only changes the pull resistors control bit field.
 *
 * Input Parameters:
 *  pMfpRegBase - base address of the MFP register set
 *  mfpOffset   - The offset of the MFPR that is being set to the
 *          specified edge trigger
 *  enable      -
 *      XLLP_ON :  Activate the configured pull up / down output
 *          during non-sleep states.
 *      XLLP_OFF:  De-activate the configured pull up / down
 *
 * Returns:
 *  XLLP_STATUS_SUCCESS     - All parameters were valid.
 *  XLLP_STATUS_WRONG_PARAMETER - Null pointer received or parameter
 *      is out of range.
 *
 * Global effects:
 *
 * Assumptions:
 *
 * Calls:
 *
 * Called by:
 *
 * Prototype:
 * XLLP_STATUS_T XllpMfpActivatePullUpDown (
 *              P_XLLP_VUINT32_T  pMfpRegBase,
 *              XLLP_UINT32_T   mfpOffset,
 *              XLLP_CONTROL_T  enable
 *              )
 ******************************************************************************/
XLLP_STATUS_T XllpMfpActivatePullUpDown (
        P_XLLP_VUINT32_T        pMfpRegBase,
        XLLP_UINT32_T           mfpOffset,
        XLLP_CONTROL_T          enable)
{
    XLLP_INT32_T value;

#if defined(XLLP_DEBUG_PARAM_CHECK)
    if (!pMfpRegBase)
        return(XLLP_STATUS_WRONG_PARAMETER);

    if ((mfpOffset < XLLP_MFP_PIN_MIN_OFFSET) ||
            (mfpOffset > XLLP_MFP_PIN_MAX_OFFSET))
        return(XLLP_STATUS_WRONG_PARAMETER);

    if ((enable != XLLP_ON) && (enable != XLLP_OFF))
        return(XLLP_STATUS_WRONG_PARAMETER);
#endif //defined(XLLP_DEBUG_PARAM_CHECK)

#if defined(CONFIG_CPU_MONAHANS_PL) || defined(CONFIG_CPU_MONAHANS_L) || defined(CONFIG_CPU_MONAHANS_LV)
    /* The expand GPIO pins just have one function */
    if (mfpOffset >= XLLP_EXP_GPIO_START_OFFSET)
        return(XLLP_STATUS_SUCCESS);
#endif

    value = *(pMfpRegBase + (mfpOffset>>2));
    value &= ~(0x1<<15);
    if (enable == XLLP_ON)
        value |= 0x1 << 15;
    *(pMfpRegBase + (mfpOffset>>2)) = value;

    return(XLLP_STATUS_SUCCESS);
}

/******************************************************************************
 * Function: XllpMfpActivatePullUpDown_List
 *
 * Description: Performs exactly the same operation as
 *  XllpMfpActivatePullUpDown(), but on a list of MFPR offsets.  Applies
 *  the specified activation or deactivation to all listed MFPs.
 *
 *
 * Input Parameters:
 *  pMfpRegBase - base address of the MFP register set
 *  pMfpOffsetList  - A pointer to the list for the offset of the MFPR
 *          that is being set to the specified edge trigger
 *  enable:
 *     XLLP_ON:  Activate the configured pull up / down output during
 *               non-LPM states for all listed MFPs.
 *     XLLP_OFF: De-activate the configured pull up / down output
 *               during non-LPM states for all listed MFPs.
 *
 * Returns:
 *  XLLP_STATUS_SUCCESS     - All parameters were valid.
 *  XLLP_STATUS_WRONG_PARAMETER - Null pointer received or parameter
 *      is out of range.
 *
 * Global effects:
 *
 * Assumptions:
 *
 * Calls:
 *
 * Called by:
 *
 * Prototype:
 * XLLP_STATUS_T XllpMfpActivatePullUpDown_List (
 *              P_XLLP_UINT32_T   pMfpRegBase,
 *              P_XLLP_UINT32_T   pMfpOffset_List,
 *              XLLP_CONTROL_T    enable
 *              )
 ******************************************************************************/
XLLP_STATUS_T XllpMfpActivatePullUpDown_List (
        P_XLLP_VUINT32_T    pMfpRegBase,
        P_XLLP_UINT32_T     pMfpOffsetList,
        XLLP_CONTROL_T      enable)
{
    XLLP_STATUS_T status;

#if defined(XLLP_DEBUG_PARAM_CHECK)
    if (!pMfpRegBase || !pMfpOffsetList)
        return(XLLP_STATUS_WRONG_PARAMETER);
#endif // defined(XLLP_DEBUG_PARAM_CHECK)

    while (*pMfpOffsetList != XLLP_MFP_PIN_EOLIST_MARKER) {
        status = XllpMfpActivatePullUpDown(pMfpRegBase,
                *pMfpOffsetList, enable);
        if (status != XLLP_STATUS_SUCCESS)
            return status;

        pMfpOffsetList ++;
    }

    return(XLLP_STATUS_SUCCESS);
}

/******************************************************************************
 * Function: XllpMfpConfigureDrivenSleepOutputLevel
 *
 * Description: Configures the specified MFP to drive the selected output
 *  level during the sleep state when the use of the driven level selection
 *  is enabled. Performs a read-modify-write operation that only changes
 *  the driven level selector bit field
 *
 * Input Parameters:
 *  pMfpRegBase - base address of the MFP register set
 *  mfpOffset   - The offset of the MFPR that is being set to the
 *          specified edge trigger
 *  level       - XLLP_HI or XLLP_LO
 *
 * Returns:
 *  XLLP_STATUS_SUCCESS     - All parameters were valid.
 *  XLLP_STATUS_WRONG_PARAMETER - Null pointer received or parameter
 *      is out of range.
 *
 * Global effects:
 *
 * Assumptions:
 *
 * Calls:
 *
 * Called by:
 *
 * Prototype:
 * XLLP_STATUS_T XllpMfpConfigureDrivenLpmOutputLevel (
 *              P_XLLP_VUINT32_T  pMfpRegBase,
 *              XLLP_UINT32_T   mfpOffset,
 *              XLLP_LEVEL_T    level
 *              )
 ******************************************************************************/
XLLP_STATUS_T XllpMfpConfigureDrivenLpmOutputLevel (
        P_XLLP_VUINT32_T pMfpRegBase,
        XLLP_UINT32_T   mfpOffset,
        XLLP_LEVEL_T    level)
{
    XLLP_INT32_T value;

#if defined(XLLP_DEBUG_PARAM_CHECK)
    if (!pMfpRegBase)
        return(XLLP_STATUS_WRONG_PARAMETER);

    if ((mfpOffset < XLLP_MFP_PIN_MIN_OFFSET) ||
            (mfpOffset > XLLP_MFP_PIN_MAX_OFFSET))
        return(XLLP_STATUS_WRONG_PARAMETER);

    if ((level != XLLP_HI) && (level != XLLP_LO))
        return(XLLP_STATUS_WRONG_PARAMETER);
#endif //defined(XLLP_DEBUG_PARAM_CHECK)

#if defined(CONFIG_CPU_MONAHANS_PL) || defined(CONFIG_CPU_MONAHANS_L) || defined(CONFIG_CPU_MONAHANS_LV)
    /* The expand GPIO pins just have one function */
    if (mfpOffset >= XLLP_EXP_GPIO_START_OFFSET)
        return(XLLP_STATUS_SUCCESS);
#endif

    value = *(pMfpRegBase + (mfpOffset>>2));
    value &= ~(0x1<<8);
    if (level == XLLP_HI)
        value |= (0x1<<8);
    *(pMfpRegBase + (mfpOffset>>2)) = value;

    return(XLLP_STATUS_SUCCESS);
}

/******************************************************************************
 * Function: XllpMfpEnableDrivenLpmOutputLevel
 *
 * Description: enable/disable the specified MFP to drive the selected output
 *  level during the sleep state when the use of the driven level selection
 *  is enabled.  Performs a read-modify-write operation that only changes
 *  the driven level selector bit field
 *
 * Input Parameters:
 *  pMfpRegBase - base address of the MFP register set
 *  mfpOffset   - The offset of the MFPR that is being set to the
 *          specified edge trigger
 *  enable      -
 *      XLLP_ON :  Activate the configured pull up / down output
 *          during non-sleep states.
 *      XLLP_OFF:  De-activate the configured pull up / down
 *
 * Returns:
 *  XLLP_STATUS_SUCCESS     - All parameters were valid.
 *  XLLP_STATUS_WRONG_PARAMETER - Null pointer received or parameter
 *      is out of range.
 *
 * Global effects:
 *
 * Assumptions:
 *
 * Calls:
 *
 * Called by:
 *
 * Prototype:
 * XLLP_STATUS_T XllpMfpEnableDrivenLpmOutputLevel (
 *              P_XLLP_VUINT32_T  pMfpRegBase,
 *              XLLP_UINT32_T   mfpOffset,
 *              XLLP_CONTROL_T  enable
 *              )
 ******************************************************************************/
XLLP_STATUS_T XllpMfpEnableDrivenLpmOutputLevel (
        P_XLLP_VUINT32_T pMfpRegBase,
        XLLP_UINT32_T   mfpOffset,
        XLLP_CONTROL_T  enable)
{
    XLLP_INT32_T value;

#if defined(XLLP_DEBUG_PARAM_CHECK)
    if (!pMfpRegBase)
        return(XLLP_STATUS_WRONG_PARAMETER);

    if ((mfpOffset < XLLP_MFP_PIN_MIN_OFFSET) ||
            (mfpOffset > XLLP_MFP_PIN_MAX_OFFSET))
        return(XLLP_STATUS_WRONG_PARAMETER);

    if ((enable != XLLP_ON) && (enable != XLLP_OFF))
        return(XLLP_STATUS_WRONG_PARAMETER);
#endif //defined(XLLP_DEBUG_PARAM_CHECK)

#if defined(CONFIG_CPU_MONAHANS_PL) || defined(CONFIG_CPU_MONAHANS_L) || defined(CONFIG_CPU_MONAHANS_LV)
    /* The expand GPIO pins just have one function */
    if (mfpOffset >= XLLP_EXP_GPIO_START_OFFSET)
        return(XLLP_STATUS_SUCCESS);
#endif

    value = *(pMfpRegBase + (mfpOffset>>2));
    value &= ~(0x1<<7);
    if (enable == XLLP_ON)
        value |= 0x1 << 7;
    *(pMfpRegBase + (mfpOffset>>2)) = value;

    return(XLLP_STATUS_SUCCESS);
}

/******************************************************************************
 * Function: XllpMfpConfigureLpmOutputLevel_List
 *
 * Description: Configures the specified MFPs to drive, pull or float the
 *  selected output levels during Low Power Modes.  As an inescapable side
 *  effect, it also sets the pull up/down configuration that is used during
 *  non-LPM states if that is enabled by XllpMfpActivatePullUpDown ().  The
 *  exact hardware settings used to achieve the specified output level are
 *  described with the definition of XLLP_MFP_LPM_OUTPUT_T in xllp_mfp_proc.h
 *  Performs a read-modify-write operation that only changes the bit fields
 *  needed for this configuration.
 *
 * Note: For basic initialization, this can be used to replace these three
 *  configuration operations for each target MFP: XllpMfpConfigurePullUpDown(),
 *  XllpMfpConfigureDrivenLpmOutputLevel() and XllpMfpEnableDrivenLpmOutputLevel().
 *
 * Input Parameters:
 *  pMfpRegBase - base address of the MFP register set
 *  mfpOffset   - The offset of the MFPR that is being set to the
 *          specified edge trigger
 *  pLpmOutputList -
 *      Pointer to a list of selectors for the desired LPM outputs of the MFPs
 *      in the *pMfpOffsetList.
 *
 * Returns:
 *  XLLP_STATUS_SUCCESS     - All parameters were valid.
 *  XLLP_STATUS_WRONG_PARAMETER - Null pointer received or parameter
 *      is out of range.
 *
 * Global effects:
 *
 * Assumptions:
 *
 * Calls:
 *
 * Called by:
 *
 * Prototype:
 * XLLP_STATUS_T XllpMfpConfigureLpmOutputLevel_List (
 *          P_XLLP_VUINT32_T    pMfpRegBase,
 *          P_XLLP_UINT32_T     pMfpOffsetList,
 *          P_XLLP_MFP_LPM_OUTPUT_T pLpmOutputList);
 ******************************************************************************/

XLLP_STATUS_T XllpMfpConfigureLpmOutputLevel_List (
        P_XLLP_VUINT32_T        pMfpRegBase,
        P_XLLP_UINT32_T         pMfpOffsetList,
        P_XLLP_MFP_LPM_OUTPUT_T pLpmOutputList)
{
    XLLP_MFP_LPM_OUTPUT_T   lpmOutput;
    XLLP_UINT32_T           mfpOffset;
    XLLP_VUINT32_T          value;

#if defined(XLLP_DEBUG_PARAM_CHECK)
    if (!pMfpRegBase || !pMfpOffsetList || !pLpmOutputList)
        return(XLLP_STATUS_WRONG_PARAMETER);
#endif // defined(XLLP_DEBUG_PARAM_CHECK)

    mfpOffset = *pMfpOffsetList;
    while (*pMfpOffsetList != XLLP_MFP_PIN_EOLIST_MARKER) {

        lpmOutput = *pLpmOutputList;

#if defined(XLLP_DEBUG_PARAM_CHECK)
        if ((mfpOffset < XLLP_MFP_PIN_MIN_OFFSET) ||
                (mfpOffset > XLLP_MFP_PIN_MAX_OFFSET)) {
            return(XLLP_STATUS_WRONG_PARAMETER);
        }
        switch (lpmOutput) {
            case XLLP_MFP_LPMO_DRIVE_LOW:
            case XLLP_MFP_LPMO_DRIVE_HIGH:
            case XLLP_MFP_LPMO_PULL_HIGH:
            case XLLP_MFP_LPMO_PULL_LOW:
            case XLLP_MFP_LPMO_FLOAT:
                break;
            default:
                return(XLLP_STATUS_WRONG_PARAMETER);
                break;
        }
#endif // defined(XLLP_DEBUG_PARAM_CHECK)

        value = *(pMfpRegBase + (mfpOffset>>2));
        value = (value & ~(XLLP_MFP_LPMO_MASK)) | lpmOutput;
        *(pMfpRegBase + (mfpOffset>>2)) = value;

        pLpmOutputList ++;
        pMfpOffsetList++;
        mfpOffset = * pMfpOffsetList;
    }

    return(XLLP_STATUS_SUCCESS);
}

/******************************************************************************
 * Function: XllpMfpEnableRdhDrm
 *
 * Description: Enable or disable the "RDH" and "Delayed Release Mode" behavior
 *  for an MFP.  The controlled behavior is actually an isolation of the
 *  Alternate Function device for both input and output.  It begins slightly
 *  before the actual Low Power Mode is applied to the AF device.  It continues
 *  until the RDH bit is cleared in the controlling Slave Low Power Management
 *  Unit register (ASCR).  It is needed for only a limited number of AF devices.
 *
 * Input Parameters:
 *  pMfpRegBase - base address of the MFP register set
 *  mfpOffset   - The offset of the MFPR that is being set to the
 *          specified edge trigger
 *  enable      - Selector to enable or disable the behavior.
 *
 * Returns:
 *  XLLP_STATUS_SUCCESS     - All parameters were valid.
 *  XLLP_STATUS_WRONG_PARAMETER - Null pointer received or parameter
 *      is out of range.
 *
 * Global effects:
 *
 * Assumptions:
 *
 * Calls:
 *
 * Called by:
 *
 * Prototype:
 * XLLP_STATUS_T XllpMfpEnableRdhDrm(
 *                 P_XLLP_VUINT32_T    pMfpRegBase,
 *                 XLLP_UINT32_T       mfpOffset,
 *                 XLLP_CONTROL_T      enable);
 ******************************************************************************/

XLLP_STATUS_T XllpMfpEnableRdhDrm(
        P_XLLP_VUINT32_T    pMfpRegBase,
        XLLP_UINT32_T       mfpOffset,
        XLLP_CONTROL_T      enable)
{
    XLLP_INT32_T value;

#if defined(XLLP_DEBUG_PARAM_CHECK)
    if (!pMfpRegBase)
        return(XLLP_STATUS_WRONG_PARAMETER);

    if ((mfpOffset < XLLP_MFP_PIN_MIN_OFFSET) ||
            (mfpOffset > XLLP_MFP_PIN_MAX_OFFSET))
        return(XLLP_STATUS_WRONG_PARAMETER);

    if ((enable != XLLP_ON) && (enable != XLLP_OFF))
        return(XLLP_STATUS_WRONG_PARAMETER);
#endif //defined(XLLP_DEBUG_PARAM_CHECK)

#if defined(CONFIG_CPU_MONAHANS_PL) || defined(CONFIG_CPU_MONAHANS_L) || defined(CONFIG_CPU_MONAHANS_LV)
    /* The expand GPIO pins just have one function */
    if (mfpOffset >= XLLP_EXP_GPIO_START_OFFSET)
        return(XLLP_STATUS_SUCCESS);
#endif

    value = *(pMfpRegBase + (mfpOffset>>2));
    value &= ~(0x1<<9);
    if (enable == XLLP_ON)
        value |= 0x1 << 9;
    *(pMfpRegBase + (mfpOffset>>2)) = value;

    return(XLLP_STATUS_SUCCESS);
}

/******************************************************************************
 * Function: XllpMfpEnableRdhDrm_List
 *
 * Description: Enable or disable the "RDH" and "Delayed Release Mode" behavior
 *  for a list of MFPs.  Applies the same enable selector to the entire list of
 *  MFPs.  The controlled behavior is actually an isolation of the Alternate
 *  Function device for both input and output.  It begins slightly before the
 *  actual Low Power Mode is applied to the AF device.  It continues until the
 *  RDH bit is cleared in the controlling Slave Low Power Management Unit
 *  register (ASCR).  It is needed for only a limited number of AF devices.
 *
 * Input Parameters:
 *  pMfpRegBase - base address of the MFP register set
 *  mfpOffset   - The offset of the MFPR that is being set to the
 *          specified edge trigger
 *  enable      - Selector to enable or disable the behavior.
 *
 * Returns:
 *  XLLP_STATUS_SUCCESS     - All parameters were valid.
 *  XLLP_STATUS_WRONG_PARAMETER - Null pointer received or parameter
 *      is out of range.
 *
 * Global effects:
 *
 * Assumptions:
 *
 * Calls:
 *
 * Called by:
 *
 * Prototype:
 * XLLP_STATUS_T XllpMfpEnableRdhDrm(
 *                 P_XLLP_VUINT32_T    pMfpRegBase,
 *                 XLLP_UINT32_T       mfpOffset,
 *                 XLLP_CONTROL_T      enable);
 ******************************************************************************/

XLLP_STATUS_T XllpMfpEnableRdhDrm_List(
        P_XLLP_VUINT32_T    pMfpRegBase,
        P_XLLP_UINT32_T     pMfpOffsetList,
        XLLP_CONTROL_T      enable)
{
    XLLP_STATUS_T status;

#if defined(XLLP_DEBUG_PARAM_CHECK)
    if (!pMfpRegBase || !pMfpOffsetList)
        return(XLLP_STATUS_WRONG_PARAMETER);
#endif // defined(XLLP_DEBUG_PARAM_CHECK)

    while (*pMfpOffsetList != XLLP_MFP_PIN_EOLIST_MARKER) {
        status = XllpMfpEnableRdhDrm(pMfpRegBase,
                *pMfpOffsetList, enable);
        if (status != XLLP_STATUS_SUCCESS)
            return status;

        pMfpOffsetList ++;
    }

    return(XLLP_STATUS_SUCCESS);
}

